package com.espirit.eap.manager.workflow;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Transient;

import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;

import com.espirit.EntityMapping;
import com.espirit.eap.ICheckModelDuplicateInfo;
import com.espirit.eap.annotation.DomainModel;
import com.espirit.eap.annotation.ModelDisplayProperty;
import com.googlecode.cswish.model.Saas;

@Entity
@DomainModel
@ModelDisplayProperty("name")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class WFTemplate extends EntityMapping implements ICheckModelDuplicateInfo, Saas  {
	private static final long serialVersionUID = -2100711490873994483L;

	private String name;
	private String description;
	
	private Boolean active;
	private String events;
	private WFCondition wfCondition;
	
	private List<WFTemplatePhase> wfTemplatePhases;
	
	private Integer sid;
	public Integer getSid() {
		return sid;
	}

	public void setSid(Integer sid) {
		this.sid = sid;
	}
	
	@Column(length=50)
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
	public void setDescription(String description) {
		this.description = description;
	}
	public String getDescription() {
		return description;
	}
	
	@Transient
	public List<WFPhase> getPhases(){
		if (this.getWfTemplatePhases() == null) return null;
		List<WFPhase> wfPhases = new ArrayList<WFPhase>();
		for(WFTemplatePhase templatePhase : this.getWfTemplatePhases()){
			wfPhases.add(templatePhase.getWfPhase());
		}
		return wfPhases;
	}

//	@ManyToMany(targetEntity=WFPhase.class, fetch=FetchType.LAZY)
//	@JoinTable(name = "WFTemplatePhases", joinColumns = @JoinColumn(name = "wftemplate_id"), inverseJoinColumns = @JoinColumn(name = "wfphase_id")  )
	List<WFPhase> wfPhases ;
	@Transient
	public List<WFPhase> getWfPhases() {
		return wfPhases;
	}

	public void setWfPhases(List<WFPhase> wfPhases) {
		this.wfPhases = wfPhases;
	}

	public List<WFPhase> safeWfPhases(){
		if (wfPhases == null){
			wfPhases = new ArrayList<WFPhase>();
		}
		return wfPhases;
	}
	
	public void setActive(Boolean active) {
		this.active = active;
	}

	public Boolean getActive() {
		return active;
	}
	
//	private List<Integer> wfEventsId;
//	@Transient
//	public List<Integer> getWfEventsId() {
//		return wfEventsId;
//	}
//	public void setWfEventsId(List<Integer> wfEventsId) {
//		this.wfEventsId = wfEventsId;
//	}
	
	public void initWFPhases(){
		if (this.getWfPhases() != null ) {
			List<WFPhase> phases = this.getWfPhases();
			for(int i = 0; i < phases.size() ; i++){
				WFPhase phase = phases.get(i);
				phase = phase.getWfPhases();
				phases.set(i, phase);
				
				addPhase(phase);
			}
		}
	}
	
	public void addPhase(WFPhase phase){
		WFTemplatePhase templatePhase = new WFTemplatePhase();
		templatePhase.setWfTemplate(this);
		templatePhase.setWfPhase(phase);
		if (this.wfTemplatePhases == null){
			this.wfTemplatePhases = new ArrayList<WFTemplatePhase>();
		}
		this.wfTemplatePhases.add(templatePhase);
	}
	
	@Transient
	public boolean isTheLastPhase(WFPhase wfphase){
		List<WFPhase> phases = getPhases();
		if (phases != null){
			if (phases.get(phases.size() -1).getId().equals(wfphase.getId())){
				return true;
			}
		}
		return false;
	}
	
	
	
	private final static String[] gatherProperties = new String[]{"name"};
	@Override
	public String[] gatherProperties() {
		return gatherProperties;
	}
	
//	@Override
//	public String[] gatherNotNullProperties() {
//		return new String[]{"wfEvents","wfPhases"};
//	}
	
	@Column(length = 1000)
	public String getEvents() {
		return events;
	}
	public void setEvents(String events) {
		this.events = events;
	}
	
	@Transient
	public String [] getSelectedEvents() {
		return selectedEvents;
	}
	public void setSelectedEvents(String [] selectedEvents) {
		this.selectedEvents = selectedEvents;
	}

	private String [] selectedEvents;
	
	@Transient
	public WFTemplate getTemplate(WorkflowAware workflowAware){
		if (workflowAware == null || events == null) return null;
		String simpleName = workflowAware.getClass().getSimpleName();
		String[] arrEvents = events.split(",");
		for(String event : arrEvents){
			if (event.equals(simpleName)) return this;
		}
		return null;
	}
	
	@ManyToOne(targetEntity=WFCondition.class,fetch=FetchType.LAZY ,cascade = CascadeType.ALL)
	public WFCondition getWfCondition() {
		return wfCondition;
	}
	public void setWfCondition(WFCondition wfCondition) {
		this.wfCondition = wfCondition;
	}
	
	public WFCondition safeWFCondtion(){
		if (this.wfCondition == null){
			this.wfCondition = new WFCondition();
		}
		return this.wfCondition;
	}

	public void verify(){
		if (wfCondition != null ){
			wfCondition.verify();
		}
	}
		
	@OneToMany(targetEntity = WFTemplatePhase.class ,orphanRemoval = true, fetch=FetchType.LAZY,  cascade = CascadeType.ALL, mappedBy = "wfTemplate")
//	@OrderBy(clause="id")
	public List<WFTemplatePhase> getWfTemplatePhases() {
		return wfTemplatePhases;
	}
	public void setWfTemplatePhases(List<WFTemplatePhase> wfTemplatePhases) {
		this.wfTemplatePhases = wfTemplatePhases;
	}
}
